import { loginAuthorization } from '@/api/user.js'
import { getCookies, getToken, removeCookies, removeToken, setToken } from '@/utils/auth'
import axios from 'axios'
import { Message } from 'element-ui'
import { throttle } from './index.js'

window.isRefreshToken = false // 是否处于刷新token状态
const requests = [] // 请求队列
const refreshTokenKey = 'refresh_token'

// 刷新token
function refreshToken() {
  // console.log('token刷新...')
  window.isRefreshToken = true
  const data = {
    grant_type: 'refresh_token',
    refresh_token: getCookies(refreshTokenKey),
    scope: 'read write'
  }
  return loginAuthorization(data)
    .then(res => {
      const { access_token, expires_in } = res
      // 将token保存至本地
      // token早于服务器端2分钟清理，保存调接口时不会报token过期
      setToken(access_token, { expires: new Date(new Date().getTime() + (expires_in - 60) * 1000) })
      // setCookies(refreshTokenKey, refresh_token, { expires: 30 })
      return res
    })
    .finally(() => {
      window.isRefreshToken = false
    })
}

const showExpire = throttle(() => {
  Message({
    message: '登录状态过期，请重新登录',
    type: 'error',
    duration: 5 * 1000,
    customClass: 'topMessage'
  })
}, 3000)

// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 20000 // request timeout
})

// request interceptor
service.interceptors.request.use(
  config => {
    // 获取token认证接口不需要操作
    if (config.url !== '/oauth/token') {
      // 获取token并加入请求头
      const token = getToken()
      if (token) {
        // token存在则正常调用接口
        config.headers['Authorization'] = `bearer ${token}`
        return config
      } else if (getCookies(refreshTokenKey)) {
        // token不存在时，刷新token后再调用token
        // 刷新token时，将所有的接口请求拦截
        if (!window.isRefreshToken) {
          refreshToken()
            .then(res => {
              return res.access_token
            })
            .then(token => {
              requests.forEach(cb => cb(token)) // 调用请求
              requests.splice(0, requests.length) // 清空请求队列
            })
            .catch(err => {
              console.log('refresh token error：' + err)
            })
        }
        return new Promise((resolve) => {
          requests.push((token) => {
            config.headers['Authorization'] = `bearer ${token}`
            resolve(config)
          })
        })
      }
    }
    return config
  },
  error => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  }
)
// response interceptor
service.interceptors.response.use(
  response => {
    const res = response.data
    if (res.code > 0) {
      Message({
        message: res.msg || 'Error',
        type: 'error',
        duration: 5 * 1000,
        customClass: 'topMessage'
      })

      if (res.code === 7) {
        removeToken()
        location.reload()
      }
    }
    return res
  },
  error => {
    if (error.response.status === 401) {
      removeToken()
      removeCookies(refreshTokenKey)
      showExpire()
      location.reload()
    } else if (error.response.status === 400 && error.response.data.code === 400) {
      removeToken()
      removeCookies(refreshTokenKey)
      Message({
        message: error.response.data.msg || '登录状态过期，请重新登录',
        type: 'error',
        duration: 5 * 1000,
        customClass: 'topMessage'
      })
      location.reload()
    } else if (error.response.status === 403) {
      // console.log(error)
      Message({
        message: '权限不足',
        type: 'error',
        duration: 5 * 1000,
        customClass: 'topMessage'
      })
    } else {
      Message({
        message: error.message,
        type: 'error',
        duration: 5 * 1000,
        customClass: 'topMessage'
      })
    }
    return Promise.reject(error)
  }
)

export default service
